/*************************************************************
 * File: ValidCodeResource.java
 * Copyright (c) 2012
 * Author: Huang Shaobin
 * Email: Shaobin.Software@gmail.com Shaobin_Software@163.com 
 * Date: Feb 27, 2013
 * Description: 
 ************************************************************/

package snow.biz.system.web.rest;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.imageio.stream.ImageOutputStream;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import org.apache.commons.collections.MapUtils;
import org.restlet.data.Form;

import snow.core.security.Operator;
import snow.core.security.annotations.Operation;
import snow.core.security.annotations.Resource;
import snow.core.web.rest.ResourceSupport;

/**
 * 验证码相关的REST接口
 * 
 * @author Shaobin.Software@gmail.com Shaobin_Software@163.com
 * @version 1.0
 */
@Path("/system/validCode")
@Resource(uri = "/validCode")
public class ValidCodeResource extends ResourceSupport {

	private final Random random = new Random();

	private String validCodeText = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";

	private int validCodeLength = 4;
	private int fontStyle = Font.BOLD;

	private String fontName = "Courier New";

	private Map<String, String> validCodeTypeMap;

	public String getFontName() {
		return this.fontName;
	}

	public int getFontStyle() {
		return this.fontStyle;
	}

	/**
	 * 获取验证码内容
	 * 
	 * @return
	 */
	protected String getValidCode() {
		final StringBuilder validCode = new StringBuilder();
		for (int i = 0; i < 4; i++) {
			validCode.append(validCodeText.charAt(random.nextInt(validCodeText.length())));
		}
		return validCode.toString();
	}

	public int getValidCodeLength() {
		return this.validCodeLength;
	}

	public String getValidCodeText() {
		return this.validCodeText;
	}

	public Map<String, String> getValidCodeTypeMap() {
		return this.validCodeTypeMap;
	}

	@GET
	@Produces(MediaType.WILDCARD)
	@Operation(name = "获取验证码信息", type = Operator.SEARCH, needCheck = false)
	public Object obtainValidCode() {
		final Form queryForm = super.getQueryAsForm();
		final String type = queryForm.getFirstValue("type");
		if (log.isInfoEnabled()) {
			log.info("The type is -> " + type);
		}
		final String name = MapUtils.getString(getValidCodeTypeMap(), type, "login_valid_code");
		if (log.isInfoEnabled()) {
			log.info("当前使用的ValidCodeType为：" + name);
		}
		// 生成验证码
		final String validCode = getValidCode();
		if (log.isInfoEnabled()) {
			log.info("当前生产的验证码为：" + validCode);
		}
		// 将验证码信息放入会话中
		putSessionValueFrom(name, validCode);
		final int width = 65, height = 20;
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
		Graphics g = image.getGraphics();
		// 以下填充背景颜色
		g.setColor(new Color(120, 160, 60));
		g.fillRect(0, 0, width, height);
		// 设置字体颜色
		g.setColor(new Color(255, 255, 255));
		g.setFont(new Font(fontName, fontStyle, height - 2));
		g.drawString(validCode, 10, 15);
		g.dispose();
		ByteArrayOutputStream output = new ByteArrayOutputStream();
		ByteArrayInputStream input = null;
		ImageOutputStream imageOut = null;
		try {
			imageOut = ImageIO.createImageOutputStream(output);
			ImageIO.write(image, "JPEG", imageOut);
			imageOut.close();
			input = new ByteArrayInputStream(output.toByteArray());
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		}
		return input;
	}

	public void setFontName(String fontName) {
		this.fontName = fontName;
	}

	public void setFontStyle(int fontStyle) {
		this.fontStyle = fontStyle;
	}

	public void setValidCodeLength(int validCodeLength) {
		this.validCodeLength = validCodeLength;
	}

	public void setValidCodeText(String validCodeText) {
		this.validCodeText = validCodeText;
	}

	public void setValidCodeTypeMap(Map<String, String> validCodeTypeMap) {
		this.validCodeTypeMap = validCodeTypeMap;
	}
}
